﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;

namespace PJ.Framework.Common
{
    /// <summary>
    /// Singleton inversion of control container broker
    /// </summary>
    public sealed class InjectionBroker : IDisposable
    {
        private static readonly InjectionBroker _Instance = new InjectionBroker();

        private Microsoft.Practices.Unity.IUnityContainer _Container;

        private InjectionBroker()
        {
        }

        /// <summary>
        /// Singleton instance
        /// </summary>
        public static InjectionBroker Instance
        {
            get
            {
                return _Instance;
            }
        }

        /// <summary>
        /// Inner injection container instance
        /// </summary>
        public object InjectionContainer
        {
            get
            {
                return Container;
            }
            set
            {
                if (value == null)
                    throw new ArgumentNullException("value");
                Container = (IUnityContainer)value;
            }
        }

        /// <summary>
        /// Resolves a instance of type 
        /// </summary>
        /// <typeparam name="T">Type to resolve</typeparam>
        /// <returns>The resolved instance</returns>
        /// <exception cref="Exception">If the type can't be resolved</exception>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
        public static T Resolve<T>()
        {
            return Instance.Container.Resolve<T>();
        }

        /// <summary>
        /// <see cref="IDisposable"/> Dispose method implementation
        /// </summary>
        public void Dispose()
        {
            if (_Container != null)
            {
                _Container.Dispose();
                _Container = null;
            }
        }

        private IUnityContainer Container
        {
            get
            {
                if (_Container == null)
                    _Container = new Microsoft.Practices.Unity.UnityContainer();
                return _Container;
            }
            set
            {
                Dispose();
                _Container = value;
            }
        }
    }
}
